import os
import subprocess

class InstallerBusy(Exception):
	'''Rises when installer is requested to install, although he is busy'''


class Installer(object):
	'''Installation controller

	@property busy is installer busy
	@property lastcode exit code of last installed app
	@property lastapp name of the last installed app
	'''

	def __init__(self, statusBar=None):
		self.statusBar = statusBar
		self.busy = False
		self.lastcode = 0
		self.lastapp = None

	def install(self, version, dryrun=False):
		'''Install application

		@param version application version to install
		'''
		if self.busy:
			raise InstallerBusy
		if self.statusBar:
			self.statusBar.showMessage('Proceeding to install '+ version.name +":"+ version.version+'...', 3000)
		self.busy = True
		self.__runInstaller(version, dryrun)
		self.busy = False
		if self.statusBar:
			self.statusBar.showMessage('Installation finished, exit code: '+str(self.lastcode)+'...', 3000)

	def __runInstaller(self, app, dryrun):
		'''Internal application install code

		@param app application to install
		@param dryrun do not execute.
		'''

		assert self.busy

		self.lastapp = app.name
		path = app.ver_path
		installer = app.installer
		inst_type = app.inst_type
		params = app.params
		if inst_type == app.MSI:
			command = ''.join(['msiexec  /i "', os.path.join(path,installer), '" ', params,])
		elif inst_type == app.EXE:
			command = os.path.join(path, installer)

		if dryrun:
			return

		popen = subprocess.Popen(command)
		self.lastcode = popen.wait()
		
	def tweak(self, tweak, dryrun=False):
		'''Install application

		@param tweak tweak to apply
		'''
		if self.busy:
			raise InstallerBusy
		if self.statusBar:
			self.statusBar.showMessage('Procceding to apply: '+tweak.desc, 3000)
		self.busy = True
		self.__runTweak(tweak, dryrun)
		self.busy = False
		if self.statusBar:
			self.statusBar.showMessage(tweak.desc+' applied.', 3000)
	
	
	def __runTweak(self, tweak, dryrun):
		assert self.busy
		print tweak.path
		command = 'regedit.exe  /S "'+tweak.path+'"'
		if dryrun:
			return
		popen = subprocess.Popen(command)
		popen.wait()
